package com.zoke.support.http;

import java.util.Date;

import android.content.Context;

import com.zoke.support.domain.CacheUrlInfo;
import com.zoke.support.http.task.AjaxCallBack;
import com.zoke.support.utils.CacheManager;
import com.zoke.support.utils.CommonUtil;
import com.zoke.support.utils.LogUtil;
import com.zoke.support.view.ZokeToast;

/**
 * http请求操作类
 * 
 * @author JackWu
 * 
 */
public class HttpStores {
	private static HttpStores mHttpStores;
	private JackHttp mHttp;

	/** 缓存更新间隔时间--1小时 仅当设置支持控制更新频率时启用 **/
	private static final int HTTP_CACHE_UPDATE_INTERVAL = 60 * 60 * 1000;// 延迟更新的作用

	private Context mContext;

	private HttpStores(Context context) {
		this.mContext = context;
		mHttp = new JackHttp();

	}

	public synchronized static HttpStores getInstense(Context context) {
		if (mHttpStores == null) {
			mHttpStores = new HttpStores(context);
		}
		return mHttpStores;
	}

	/** 获取http引用 **/
	public JackHttp getHttp() {
		return mHttp;
	}

	/** 没有网络连接时，处理缓存结果 **/
	private void handleNoNetResult(ZokeParams param) {
		CacheUrlInfo cache = CacheManager.getManager(mContext).getCache(param);
		if (cache != null) {
			// 直接回调成功 并把数据返给UI界面
			param.setResult(cache.getJsonString());
			CallBackStores.getCallback().notifySuccess(param);
			LogUtil.i("网络连接错误，执行读取缓存的操作");
			ZokeToast.showNetFailed(mContext);
		} else {
			ZokeErro erro = new ZokeErro();
			erro.setErrorNo(0);
			erro.setStrMsg("没有网络连接");
			param.setResult(erro);
			LogUtil.i("网络连接错误，更新异常");
			CallBackStores.getCallback().notifyFaile(param);
		}
	}

	/** 控制某些接口的更新频率 **/
	private boolean handleControlUpdate(ZokeParams param) {
		CacheUrlInfo cache = CacheManager.getManager(mContext).getCache(param);
		if (cache == null) {
			LogUtil.e("无法控制更新频率,没有进行缓存");
			return false;
		} else {
			// 如果时间大于控制内的时间时，直接返回缓存刷新界面 然后则调用网络请求，成功以后再次刷新界面
			if (new Date().getTime() - cache.getUpdateTime() > HTTP_CACHE_UPDATE_INTERVAL) {
				LogUtil.e("距离上次请求超过1小时，优先返回缓存结果，网络请求成功以后会再次返回结果");
				param.setResult(cache.getJsonString());
				CallBackStores.getCallback().notifySuccess(param);
				return false;
			}
			// 直接回调成功 并把数据返给UI界面
			param.setResult(cache.getJsonString());
			CallBackStores.getCallback().notifySuccess(param);
			LogUtil.e("执行控制更新频率--不在进行网络请求");
			return true;
		}

	}

	/**
	 * get方式获取
	 * 
	 * @param param
	 */
	public void get(ZokeParams param) {

		final ZokeParams mParam = param;
		/** 如果判断没有网络 则直接读出缓存 没有缓存则直接回调fails **/
		if (!CommonUtil.getNetWorkStates(mContext) && param.isUseCache()) {
			handleNoNetResult(mParam);
			return;
		}

		// 只设置使用缓存--但不设置更新频率的时候加载缓存更新下界面
		if (param.isUseCache() && !param.isControlUpdate()) {
			CacheUrlInfo cache = CacheManager.getManager(mContext).getCache(
					param);
			if (cache != null) {
				// 使用缓存，但不设置更新频率
				LogUtil.e("使用缓存,并更新界面，但不控制更新频率");
				param.setResult(cache.getJsonString());
				CallBackStores.getCallback().notifySuccess(param);
			}
		}

		/** 有网络时，是否需要判断更新频率 **/
		if (param.isControlUpdate()) {
			boolean isWork = handleControlUpdate(mParam);
			if (isWork) {
				return;
			}
		}

		/** 执行网络请求的真正方法 **/
		mHttp.get(mParam.getUrl(), mParam, new AjaxCallBack<String>() {
			@Override
			public void onSuccess(String t) {
				super.onSuccess(t);
				// 这里要将 params的结果返回给callBack
				// 这里如果不想返回程序员json字符串，需要用反序列化方式直接返回
				mParam.setResult(t);
				CallBackStores.getCallback().notifySuccess(mParam);
				// 存储缓存
				if (mParam.isUseCache())
					CacheManager.getManager(mContext).saveCache(mParam);
			}

			@Override
			public void onFailure(Throwable t, int errorNo, String strMsg) {
				super.onFailure(t, errorNo, strMsg);
				// 处理错误代码并更新对应Activity的失败方法
				ZokeErro zkErro = new ZokeErro();
				zkErro.setErrorNo(errorNo);
				zkErro.setT(t);
				zkErro.setStrMsg(strMsg);
				mParam.setResult(zkErro);
				CallBackStores.getCallback().notifyFaile(mParam);
			}

		});
	}

	/**
	 * 从网络获取数据
	 * 
	 * @param param
	 * @param url
	 * @param ajaxParam
	 */
	public void find(ZokeParams param) {
		final ZokeParams mParam = param;
		/** 如果判断没有网络 则直接读出缓存 没有缓存则直接回调fails **/
		if (!CommonUtil.getNetWorkStates(mContext) && param.isUseCache()) {
			handleNoNetResult(mParam);
			return;
		}

		// 只设置使用缓存--但不设置更新频率的时候加载缓存更新下界面
		if (param.isUseCache() && !param.isControlUpdate()) {
			CacheUrlInfo cache = CacheManager.getManager(mContext).getCache(
					param);
			if (cache != null) {
				// 使用缓存，但不设置更新频率
				LogUtil.e("使用缓存,并更新界面，但不控制更新频率");
				param.setResult(cache.getJsonString());
				CallBackStores.getCallback().notifySuccess(param);
			}
		}

		/** 有网络时，是否需要判断更新频率 **/
		if (param.isControlUpdate()) {
			boolean isWork = handleControlUpdate(mParam);
			if (isWork) {
				return;
			}
		}

		/** 执行网络请求的真正方法 **/
		mHttp.post(mParam.getUrl(), mParam, new AjaxCallBack<String>() {
			@Override
			public void onSuccess(String t) {
				super.onSuccess(t);
				// 这里要将 params的结果返回给callBack
				// 这里如果不想返回程序员json字符串，需要用反序列化方式直接返回
				mParam.setResult(t);
				CallBackStores.getCallback().notifySuccess(mParam);
				// 存储缓存
				if (mParam.isUseCache())
					CacheManager.getManager(mContext).saveCache(mParam);
			}

			@Override
			public void onFailure(Throwable t, int errorNo, String strMsg) {
				super.onFailure(t, errorNo, strMsg);
				// 处理错误代码并更新对应Activity的失败方法
				ZokeErro zkErro = new ZokeErro();
				zkErro.setErrorNo(errorNo);
				zkErro.setT(t);
				zkErro.setStrMsg(strMsg);
				mParam.setResult(zkErro);
				CallBackStores.getCallback().notifyFaile(mParam);
			}

		});

	}

}
